package service

import (
	"errors"
	"reflect"
	"sieve_admin_server_userpass/pkg/im3/msgpack"
	"strings"
	"sync"
)

var (
	apiHandlers = map[string]func(*msgpack.Req) interface{}{}
	apiLock     = sync.Mutex{}
)

type ApiHandler interface {
	Handle(caller string) interface{}
}

func AddApiHandler(api ApiHandler) {
	apiLock.Lock()
	defer apiLock.Unlock()

	t := reflect.TypeOf(api).Elem()
	name := t.Name()
	if !strings.HasPrefix(name, "api_") {
		return
	}
	name = name[4:]
	apiHandlers[name] = func(r *msgpack.Req) interface{} {
		v := reflect.New(t).Interface()
		if err := r.Parse(v); err != nil {
			return err
		}
		return v.(ApiHandler).Handle(r.Caller)
	}
}

func handleApi(data []byte) []byte {
	p, err := msgpack.ParseReq(data)
	if err != nil {
		b, _ := msgpack.NewResp(err)
		return b
	}
	h, ok := apiHandlers[p.Name]
	if !ok {
		b, _ := msgpack.NewResp(errors.New("api not found: " + p.Name))
		return b
	}
	ret := h(p)
	if ret == nil {
		return nil
	}
	b, err := msgpack.NewResp(ret)
	if err != nil {
		b, _ := msgpack.NewResp(err)
		return b
	}
	return b
}
